package com.example.redissondemo.demos.web;

import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

/**
 * @ClassName: TestController
 * @Description:
 * @Date 2024/01/29 09:40
 * @Author songshaoqiu
 **/
@RestController
@Slf4j
public class TestController {

    @Autowired
    public RedissonClient redissonClient;

    @GetMapping("/lock")
    public String testLock(@RequestParam("order") String order) throws InterruptedException {
        log.info("参数【{}】",order);
        RLock lock = redissonClient.getLock("lock"+order);
        //1、等待锁的时间 必须 小于锁的持有时间 即waitTime < leaseTime
        //2、锁的持有时间 理论上 大于业务执行时间，否则 在使用tryLock（A,B,C）的情况下。并不会走看门狗机制。锁并不会自动续期。
        //在这种情况下。解锁的时候会发先并没有占有锁（因为锁已被释放）  但是好像并不影响
        //这个锁 理论上来讲 应该是分场景  如果是针对多个用户 抢一个  那么锁 就不需要加 用户id
        //                          如果是针对 防止重复点击  那么就要加上用户id  因为是针对这个用户
        boolean b = lock.tryLock(1L, 5L, TimeUnit.SECONDS);
        if (!b){
            log.info("线程【{}】，占有锁失败", Thread.currentThread().getName());
            return "获取锁失败";
        }
        try {
            log.info("线程【{}】，占有锁成功---执行业务", Thread.currentThread().getName());
            Thread.sleep(3000L);

        }catch (Exception e){

        }finally {
            log.info("当前线程【{}】是否占有锁【{}】",Thread.currentThread().getName(),lock.isLocked());
            if (lock.isLocked()&&lock.isHeldByCurrentThread()){
                System.out.println("线程--"+Thread.currentThread().getName()+"释放锁");
                lock.unlock();
            }
        }

        return "hello";
    }

    @GetMapping("/testSentinel")
    public String testSentinel(){
        log.info("进入到方法" );
        return "hello world";
    }
}
